package cn.jwm.permission.service.impl;


import cn.jwm.annotation.JwmPermission;
import cn.jwm.permission.domain.Permission;
import cn.jwm.permission.mapper.PermissionMapper;
import cn.jwm.permission.service.IPermissionScanService;
import cn.jwm.utils.ClassUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author Administrator
 */
@Service
public class PermissionScanServiceImpl implements IPermissionScanService {

    @Value("${jwm.permission.scanPackage}")
    private String scanPackage;

    @Resource
    private PermissionMapper permissionMapper;

    /**
     * 容器启动,权限扫描
     */
    @Override
    public void scan() {
        List<Class> classes = ClassUtils.getAllClassName(this.scanPackage);
        List<Permission> permissions = new ArrayList<>();
        for (Class aClass : classes) {
           JwmPermission classAnnotation = (JwmPermission)aClass.getAnnotation(JwmPermission.class);
            if(Objects.isNull(classAnnotation)){
                continue;
            }
            Permission parent = new Permission();
            parent.setName(classAnnotation.name());
            parent.setDescs(classAnnotation.descs());
            RequestMapping classRequestMapping = (RequestMapping)aClass.getAnnotation(RequestMapping.class);
            if(Objects.nonNull(classRequestMapping)){
                parent.setUrl(classRequestMapping.value()[0]);
            }
            parent.setSn(aClass.getSimpleName());
            permissions.add(parent);
            Method[] methods = aClass.getMethods();
            for (Method method : methods) {
              JwmPermission methodAnnotation = method.getAnnotation(JwmPermission.class);
                if(Objects.isNull(methodAnnotation)){
                    continue;
                }
                Permission permission = new Permission();
                permission.setName(methodAnnotation.name());
                permission.setDescs(methodAnnotation.descs());
                permission.setUrl(getUrl(aClass, method));
                permission.setSn(aClass.getSimpleName()+":"+method.getName());
                permission.setParent(parent);
                permissions.add(permission);
            }
        }

        permissionMapper.deleteAll();

        // 添加权限
        if(!CollectionUtils.isEmpty(permissions)){
            for (Permission permission : permissions) {
                permissionMapper.add(permission);
            }
        }
    }

    private String getUrl(Class aClass,Method method){
        String url = "";
        RequestMapping classRequestMapping = (RequestMapping)aClass.getAnnotation(RequestMapping.class);
        if(Objects.nonNull(classRequestMapping)){
            url = classRequestMapping.value()[0];
        }
        GetMapping getMapping = (GetMapping)method.getAnnotation(GetMapping.class);
        if(Objects.nonNull(getMapping) && getMapping.value().length > 0){
            url += getMapping.value()[0];
        }
        PostMapping postMapping = (PostMapping)method.getAnnotation(PostMapping.class);
        if(Objects.nonNull(postMapping) && postMapping.value().length > 0){
            url += postMapping.value()[0];
        }
        PutMapping putMapping = (PutMapping)method.getAnnotation(PutMapping.class);
        if(Objects.nonNull(putMapping) && putMapping.value().length > 0){
            url += putMapping.value()[0];
        }
        DeleteMapping deleteMapping = (DeleteMapping)method.getAnnotation(DeleteMapping.class);
        if(Objects.nonNull(deleteMapping) && deleteMapping.value().length > 0){
            url += deleteMapping.value()[0];
        }
        PatchMapping patchMapping = (PatchMapping)method.getAnnotation(PatchMapping.class);
        if(Objects.nonNull(patchMapping) && patchMapping.value().length > 0){
            url += patchMapping.value()[0];
        }
        return url;
    }

    public static void main(String[] args) {
        List<Permission> permissions = new ArrayList<>();
        Permission parent = new Permission();   // 父权限
        permissions.add(parent);

        Permission permission = new Permission();   // 子权限
        permission.setParent(parent);       // 给子权限添加父权限
        permissions.add(permission);

        parent.setId(1L);       // 修改父权限
        permissions.forEach(System.out::println);
    }
}
